home *** CD-ROM | disk | FTP | other *** search
/ Shareware Grab Bag / Shareware Grab Bag.iso / 090 / dump.aqm / dump.asm
Encoding:
Assembly Source File  |  1984-04-25  |  13.8 KB  |  343 lines

  1.  
  2.         name    dump
  3.         page    55,132
  4.         title   'DUMP --- Display File Contents' 
  5.  
  6. ; DUMP --- a utility to display the contents of a file in hex
  7. ; and ASCII format.  Requires PC-DOS 2.0 or MS-DOS 2.0.
  8.  
  9. ; Used in the form:
  10. ; A>dump path\filename.ext  [ >device ]
  11. ; (item in square brackets is optional)
  12.  
  13. ; version 1.0   March 25, 1984 
  14. ; Copyright (c) 1984 by Ray Duncan
  15. ; May be freely reproduced for non-commercial use. 
  16.  
  17. cr      equ     0dh             ;ASCII carriage return
  18. lf      equ     0ah             ;ASCII line feed
  19. blank   equ     20h             ;ASCII space code
  20.  
  21. command equ     80h             ;buffer for command tail
  22.  
  23. blksize equ     128             ;size of input file records
  24.  
  25. output_handle equ 1             ;handle of standard output device
  26.                                 ;(can be redirected)
  27. error_handle equ 2              ;handle of standard error device
  28.                                 ;(not redirectable)
  29.  
  30. cseg    segment para public 'CODE'
  31.  
  32.         assume  cs:cseg,ds:data,es:data,ss:stack
  33.  
  34.  
  35. dump    proc    far             ;entry point from PC-DOS
  36.  
  37.         push    ds              ;save DS:0000 for final
  38.         xor     ax,ax           ;return to PC-DOS
  39.         push    ax
  40.         mov     ax,data         ;make our data segment
  41.         mov     es,ax           ;addressable via ES register.
  42.         mov     ah,30h          ;check version of PC-DOS.       
  43.         int     21h
  44.         cmp     al,2
  45.         jae     dump1           ;proceed, DOS 2.0 or greater.
  46.         mov     dx,offset msg3  ;DOS 1.x --- print error message;
  47.         mov     ax,es           ;we must use the old PC-DOS
  48.         mov     ds,ax           ;string output function since
  49.         mov     ah,9            ;handles are not available in
  50.         int     21h             ;this version of PC-DOS.
  51.         ret
  52.  
  53. dump1:  call    get_filename    ;get path and file spec. for
  54.                                 ;input file from command line tail.
  55.         mov     ax,es           ;set DS=ES for remainder
  56.         mov     ds,ax           ;of program.
  57.         jnc     dump2           ;jump, got acceptable name.
  58.         mov     dx,offset msg2  ;missing or illegal filespec,
  59.         mov     cx,msg2_length
  60.         jmp     dump9           ;print error message and exit.
  61.  
  62. dump2:  call    open_input      ;now try to open input file
  63.         jnc     dump3           ;jump,opened input ok
  64.         mov     dx,offset msg1  ;open of input file failed,
  65.         mov     cx,msg1_length
  66.         jmp     dump9           ;print error msg and exit.
  67.  
  68. dump3:  call    read_block      ;initialize input file buffer
  69.         jnc     dump4           ;jump,got a block
  70.         mov     dx,offset msg4  ;empty file,print error
  71.         mov     cx,msg4_length
  72.         jmp     dump9           ;message and exit
  73.  
  74.                                 ;file successfully opened,             
  75. dump4:                          ;now convert and display it! 
  76.         call    get_char        ;read 1 character from input.
  77.         jc      dump8           ;jump, end of file
  78.         inc     input_addr      ;update relative file position
  79.         or      bx,bx           ;is this 1st char of block?
  80.         jnz     dump5           ;no
  81.         call    print_heading
  82. dump5:  and     bx,0fh          ;is this first byte of 16?
  83.         jnz     dump6           ;no,jump
  84.         push    ax              ;save the byte
  85.         mov     di,offset output;convert relative file addr. 
  86.         mov     ax,input_addr   ;for output string
  87.         call    conv_word 
  88.         pop     ax
  89. dump6:                          ;store ASCII version of character,
  90.                                 ;if it is alphanumeric,
  91.         mov     di,offset outputb
  92.         add     di,bx           ;calculate output string address
  93.         mov     byte ptr [di],'.' ;if it is control character,
  94.         cmp     al,blank        ;just print a dot.      
  95.         jb      dump7           ;jump, not alphanumeric.
  96.         cmp     al,7eh          
  97.         ja      dump7           ;jump, not alphanumeric.
  98.         mov     [di],al         ;store ASCII character.
  99. dump7:                          ;now convert binary byte
  100.                                 ;to hex  ASCII equivalent.
  101.         push    bx              ;save offset 0-15 of this byte.
  102.                                 ;calc. its position in
  103.                                 ;output string.
  104.         mov     di,offset outputa
  105.         add     di,bx           ;base addr + (offset*3)
  106.         add     di,bx
  107.         add     di,bx
  108.         call    conv_byte       ;convert data byte to hex 
  109.         pop     bx              ;restore byte offset
  110.         cmp     bx,0fh          ;16 bytes converted yet?
  111.         jne     dump4           ;no,get another byte
  112.         mov     dx,offset output
  113.         mov     cx,output_length
  114.         call    write_std       ;yes, print the line
  115.         jmp     dump4           ;get next char. from input file.
  116.  
  117. dump8:                          ;end of file detected,
  118.         call    close_input     ;close input file. 
  119.         ret                     ;now return to PC-DOS.
  120.  
  121. dump9:                          ;come here to print message 
  122.                                 ;on standard error device, 
  123.         call    write_error     ;and return control to PC-DOS
  124.         ret
  125.  
  126. dump    endp
  127.  
  128.  
  129. get_filename proc near          ;process name of input file
  130.                                 ;return Carry = 0 if successful
  131.                                 ;return Carry = 1 if no filename
  132.                                 ;DS:SI <- addr command line     
  133.         mov     si,offset command
  134.                                 ;ES:DI <- addr filespec buffer
  135.         mov     di,offset input_name
  136.         cld
  137.         lodsb                   ;any command line present?
  138.         or      al,al           ;return error status if not.
  139.         jz      get_filename4
  140. get_filename1:                  ;scan over leading blanks
  141.         lodsb                   ;to file name.
  142.         cmp     al,cr           ;if we hit carriage return...
  143.         je      get_filename4   ;jump, name is missing
  144.         cmp     al,20h          ;is this a blank?
  145.         jz      get_filename1   ;if so keep scanning.
  146. get_filename2:                  ;found first char of name,
  147.         stosb                   ;move last char. to output
  148.                                 ;file name buffer. 
  149.         lodsb                   ;check next character, found
  150.         cmp     al,cr           ;carriage return yet?   
  151.         je      get_filename3   ;yes,exit with success code.
  152.         cmp     al,20h          ;is this a blank?
  153.         jne     get_filename2   ;if not keep moving chars.
  154. get_filename3:                  ;exit with carry =0
  155.         clc                     ;for success flag
  156.         ret
  157. get_filename4:                  ;exit with carry =1
  158.         stc                     ;for error flag
  159.         ret
  160. get_filename endp 
  161.  
  162. open_input proc near            ;open input file
  163.                                 ;DS:DX=addr filename
  164.         mov     dx,offset input_name
  165.         mov     al,0            ;AL=0 for read only
  166.         mov     ah,3dh          ;function 3dh=open
  167.         int     21h             ;handle returned in AX,
  168.         mov     input_handle,ax ;save it for later.
  169.         ret                     ;CY is set if error
  170. open_input endp
  171.  
  172. close_input proc near           ;close input file
  173.         mov     bx,input_handle ;BX=handle
  174.         mov     ah,3eh
  175.         int     21h
  176.         ret
  177. close_input endp
  178.  
  179. get_char proc   near            ;get one character from input buffer
  180.                                 ;return AL = char, BX = buffer offset
  181.                                 ;return CY flag = 1 if end of file
  182.         mov     bx,input_ptr    ;is pointer at end of buffer?
  183.         cmp     bx,blksize      
  184.         jne     get_char1       ;no,jump
  185.                                 ;yes, buffer is exhausted, 
  186.         mov     input_ptr,0
  187.         call    read_block      ;new block must be read from disk.
  188.         jnc     get_char        ;got block, start routine over.
  189.         ret                     ;end of file detected
  190.                                 ;so return CY flag = True.
  191. get_char1:                      ;get data byte into AL,
  192.         mov     al,[input_buffer+bx]
  193.         inc     input_ptr       ;bump input buffer pointer.
  194.         clc                     ;return CY flag =0 since 
  195.         ret                     ;not end of file.
  196. get_char endp   
  197.  
  198.  
  199. read_block proc near            ;read block of data from input file.
  200.                                 ;return CY flag = 0 if read ok.
  201.                                 ;       CY flag = 1 if end of file.
  202.         mov     bx,input_handle ;request read from PC-DOS.
  203.         mov     cx,blksize
  204.         mov     dx,offset input_buffer
  205.         mov     ah,3fh
  206.         int     21h
  207.                                 ;initialize pointers
  208.         inc     input_block
  209.         mov     input_ptr,0 
  210.         or      ax,ax           ;was anything read in? (the OR 
  211.                                 ; incidentally turns off the CY flag)
  212.         jnz     read_block1     ;yes,jump
  213.         stc                     ;no,end of file so return CY=True
  214. read_block1:
  215.         ret
  216. read_block endp
  217.  
  218. write_std proc  near            ;write string to standard output.
  219.                                 ;call DX = addr of output string
  220.                                 ;     CX = length of string
  221.         mov     bx,output_handle;BX=handle for standard list device.
  222.         mov     ah,40h          ;function 40h=write to device.
  223.         int     21h             ;request service from DOS.
  224.         ret
  225. write_std endp
  226.  
  227. write_error proc near           ;write string to standard error device.
  228.                                 ;call DX = addr of output string
  229.                                 ;     CX = length of string
  230.         mov     bx,error_handle ;BX=handle for standard error device.
  231.         mov     ah,40h          ;function 40h=write to device.
  232.         int     21h             ;request service from DOS.
  233.         ret
  234. write_error endp
  235.  
  236. print_heading proc near         ;print record number and heading
  237.         push    ax              ;for a block of data
  238.         push    bx              ;first save registers   
  239.         mov     di,offset headinga
  240.         mov     ax,input_block 
  241.         call    conv_word       ;convert record number to ASCII
  242.         mov     dx,offset heading
  243.         mov     cx,heading_length
  244.         call    write_std       ;now print heading
  245.         pop     bx              ;restore registers
  246.         pop     ax
  247.         ret                     ;and exit
  248. print_heading endp
  249.  
  250. conv_word proc near             ;convert 16-bit binary word 
  251.                                 ; to hex ASCII
  252.                                 ;call with AX=binary value
  253.                                 ;          DI=addr to store string
  254.                                 ;returns AX, DI, CX destroyed
  255.         push    ax
  256.         mov     al,ah
  257.         call    conv_byte       ;convert upper byte     
  258.         pop     ax
  259.         call    conv_byte       ;convert lower byte
  260.         ret
  261. conv_word endp
  262.  
  263. conv_byte proc    near          ;convert binary byte to hex ASCII
  264.                                 ;call with AL=binary value
  265.                                 ;          DI=addr to store string
  266.                                 ;returns   AX, DI, CX modified 
  267.  
  268.         sub     ah,ah           ;clear upper byte
  269.         mov     cl,16
  270.         div     cl              ;divide binary data by 16
  271.         call    ascii           ;the quotient becomes the first
  272.         stosb                   ;ASCII character
  273.         mov     al,ah
  274.         call    ascii           ;the remainder becomes the
  275.         stosb                   ;second ASCII character
  276.         ret
  277. conv_byte endp
  278.  
  279. ascii   proc    near            ;convert bottom 4 bits in AL 
  280.         add     al,'0'          ;into the hex ASCII character
  281.         cmp     al,'9'
  282.         jle     ascii2          ;jump if in range 0-9,
  283.         add     al,'A'-'9'-1    ;offset it to range A-F,
  284. ascii2: ret                     ;return ASCII char. in AL.
  285. ascii   endp
  286.  
  287. cseg    ends
  288.  
  289.  
  290. data    segment para public 'DATA'
  291.  
  292. input_name      db      64 dup (0)      ;buffer for input filespec
  293.  
  294. input_handle    dw      0               ;token from PCDOS for input file.
  295.  
  296. input_ptr       dw      0               ;pointer to input deblocking buffer
  297.  
  298. input_addr      dw      -1              ;relative address in file 
  299. input_block     dw      0               ;current 128 byte block number
  300.  
  301. output          db      'nnnn',blank,blank
  302. outputa         db      16 dup ('00',blank)
  303.                 db      blank
  304. outputb         db      '0123456789ABCDEF',cr,lf 
  305. output_length   equ     $-output
  306.  
  307. heading         db      cr,lf,'Record',blank
  308. headinga        db      'nnnn',blank,blank,cr,lf
  309.                 db      7 dup (blank)
  310.                 db      '0  1  2  3  4  5  6  7  '
  311.                 db      '8  9  A  B  C  D  E  F',cr,lf
  312. heading_length  equ     $-heading
  313.  
  314. input_buffer    db      blksize dup (?) ;deblocking buffer for input file
  315.  
  316. msg1            db      cr,lf
  317.                 db      'Cannot find input file.'
  318.                 db      cr,lf
  319. msg1_length     equ     $-msg1
  320.  
  321. msg2            db      cr,lf
  322.                 db      'Missing file name.'
  323.                 db      cr,lf
  324. msg2_length     equ     $-msg2
  325.  
  326. msg3            db      cr,lf
  327.                 db      'Requires PC-DOS version 2 or greater.'
  328.                 db      cr,lf,'$'
  329.  
  330. msg4            db      cr,lf,'Empty file.',cr,lf
  331. msg4_length     equ     $-msg4
  332.  
  333. data    ends    
  334.  
  335.  
  336. stack   segment para stack 'STACK'
  337.         db      64 dup (?)
  338. stack   ends
  339.  
  340.         end     dump
  341. 
  342.  
  343. Press ENTER to continue: